package cn.chess.service.impl;

import cn.chess.domain.Boxes;
import cn.chess.domain.Orders;
import cn.chess.domain.User;
import cn.chess.mapper.BoxesMapper;
import cn.chess.mapper.OrdersMapper;
import cn.chess.service.OrderService;
import cn.chess.service.UserService;
import cn.chess.util.AppointmentTask;
import cn.chess.util.DateTimeUtils;
import cn.chess.util.SnowflakeIdGenerator;
import cn.chess.vo.OrdersVO;
import cn.chess.vo.PayOrderVO;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

import static cn.chess.util.OrderStatus.*;
import static cn.chess.util.PageType.PAGE_SIZE;

/**
 * @author zgc
 * @description 针对表【order(订单表)】的数据库操作Service实现
 * @createDate 2023-03-27 10:32:08
 */
@Service
public class OrderServiceImpl implements OrderService {

    @Autowired
    private OrdersMapper orderMapper;
    @Autowired
    private SnowflakeIdGenerator snowflakeIdGenerator;
    @Autowired
    private UserService userService;
    @Autowired
    private BoxesMapper boxesMapper;

    @Override
    @Transactional
    public Orders places(OrdersVO ordersVO) {
        // 1. 生成订单号
        long orderId = snowflakeIdGenerator.nextId();
//        选择时间段
        String selectArray = date2ArrayString(ordersVO.getStartTime(), ordersVO.getExpiryTime(), 30);

        // 2. 创建订单
        Orders orders = new Orders();
        BeanUtils.copyProperties(ordersVO, orders);
        orders.setOid("CR" + orderId);
//        设置开始时间和结束时间
        orders.setStartTime(new Date(ordersVO.getStartTime()));
        orders.setExpiryTime(new Date(ordersVO.getExpiryTime()));
        orders.setSelectTime(selectArray);
//        初始化订单状态 未支付  未使用
        orders.setStatus(ORDER_STATUS_UNUSED);
        orders.setPaystatus(PAY_DEFEATED);
        // 3.保存订单
        orderMapper.insert(orders);
        //4. 返回订单信息
        return orders;
    }

    @Override
    public Boolean determineOpen(String openid) {
        QueryWrapper<Orders> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("openid", openid);
        List<Orders> orders = orderMapper.selectList(queryWrapper);
        for (Orders order : orders
        ) {
            Integer status = order.getStatus();
            if (status == 0) {
                return true;
            }
        }
        return false;
    }

    @Override
    public List<Orders> getOrderList(String openid, Integer type, Integer page) {
        //        计算分页
        page = page == 0 ? 1 : page;

        QueryWrapper<Orders> wrapper = new QueryWrapper<>();
        //        根据openid和类型查询、分页查询
        wrapper.eq("openid", openid);

        /*
         * createTime 订单创建时间
         * status 订单是否已消费(0：未消费 1：已消费)
         * paystatus 订单支付状态 (0 : 未支付   1 ： 已支付)
         * expiryTime 订单结束时间
         * */
        switch (type) {
            case 1:
//                type =1 未支付   订单创建时间小于30分钟  订单结束时间没过期

                break;
            case 2:
//                type=2 以预约    定单支付成功  订单结束时间未过期   订单未使用
                break;
            case 3:
//                type =3 已使用   订单结束时间没过期   订单已使用
                break;
            case 4:
                /*
                 * type =4 已过期
                 * 1. 订单未支付 超时   创建时间大于 30分钟 没支付的就算 支付超时过期
                 * 2，订单支付成功了 ，但是没有使用 订单结束时间过期  */
                break;
            default:

                break;
        }

        Page<Orders> ordersPage = orderMapper.selectPage(new Page<>(page, PAGE_SIZE), wrapper);
        List<Orders> ordersList = ordersPage.getRecords().stream().map((item) -> {
            Integer bid = item.getBid();
            Boxes id = boxesMapper.selectOne(new QueryWrapper<Boxes>().eq("id", bid));
            item.setBoxes(id);
            return item;
        }).collect(Collectors.toList());
        return ordersList;
    }

    @Override
    public Orders getOrderByOrderid(String orderid) {

        Orders orders = orderMapper.selectOne(new QueryWrapper<Orders>().eq("oid", orderid));

        return orders;
    }

    @Override
    public Integer payOrder(PayOrderVO payOrderVO) {
        //        查询订单

        Orders orders = orderMapper.selectOne(
                new QueryWrapper<Orders>()
                        .eq("oid", payOrderVO.getOrderId())
                        .eq("openid", payOrderVO.getOpenid()));

        if (orders.getPaystatus() == 1) {
            //           已经支付过了
            return 2;
        }
        //        1. 查询用户余额
        String openid = payOrderVO.getOpenid();

        User user = userService.getUserByOpenid(openid);
        if (user == null) {
            //            信息错误
            return 3;
        }

        BigDecimal userBalance = user.getBalance();
        //        2.判断用户余额是否充足
        if (userBalance.compareTo(orders.getPrice()) < 0) {
            //  TODO      2.1用户余额不足  返回 信息告知前端vx支付
            return 0;

        }
        //        3.扣余额
        userBalance = userBalance.subtract(orders.getPrice());
        user.setBalance(userBalance);
        int update = userService.update(user);
        //        判断余额是否扣成功
        if (update > 0) {
            //        4.改变订单状态
            updataPayStatus(payOrderVO.getOrderId(), PAY_SUCCESS);
            //        5.返回支付成功信息

            //调用预约任务


            AppointmentTask appointmentTask = new AppointmentTask(orders.getExpiryTime(), "预约时间");
            appointmentTask.schedule();
            return 1;
        }
        return 0;

    }

    @Override
    public void updataPayStatus(String orderId, int payStatus) {
        Orders orders = new Orders();
        orders.setOid(orderId);
        orders.setPaystatus(payStatus);

        orderMapper.updateById(orders);
    }

    @Override
    public List<Orders> getOrderByUserID(Integer id) {
        LambdaQueryWrapper<Orders> wrapper = new LambdaQueryWrapper();
        wrapper.eq(Orders::getUid, id);
        List<Orders> orderList = orderMapper.selectList(wrapper);
        return orderList;
    }


    /**
     * @Description:
     * @Author: WangQiYang
     * @Date:
     * @param startTime:
     * @param expiryTime:
     * @return: java.lang.String[]
     **/
    /**
     * @param start:   开始日期 时间戳
     * @param end:     结束日期  时间戳
     * @param interval : 精度  时间间隔  分钟
     * @Description: 日期时间段按找指定间隔分段
     * @Author: WangQiYang
     * @Date:
     * @return: java.lang.String[]
     **/
    public String date2ArrayString(Long start, Long end, Integer interval) {

        Date startDate = DateTimeUtils.convertLong2Date("HH:mm", start);
        Date endDate = DateTimeUtils.convertLong2Date("HH:mm", end);
        List<String> list = new ArrayList<>();
        while (startDate.getTime() <= endDate.getTime()) {
            list.add(DateTimeUtils.convertDate2String("HH:mm", startDate));
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(startDate);
            calendar.add(Calendar.MINUTE, interval);
            if (calendar.getTime().getTime() > endDate.getTime()) {
                if (!startDate.equals(endDate)) {
                    list.add(DateTimeUtils.convertDate2String("HH:mm", endDate));
                }
                startDate = calendar.getTime();
            } else {
                startDate = calendar.getTime();
            }

        }

        String[] strArr = new String[list.size()];
        for (int i = 0; i < strArr.length; i++) {
            strArr[i] = list.get(i);
        }

        JSONArray jsonArray = (JSONArray) JSONArray.toJSON(strArr);


        return jsonArray.toString();
    }
}




